#undef UNICODE
#undef _UNICODE
#include <stdio.h>
#include <easyx.h>
#include <time.h>
#include <stdlib.h>
#include <graphics.h>
#include <conio.h>
#include <windows.h>

//木板最大数量
const int max_blank = 13;
//木板间距
const int max_distance = 100;

//木板结构体
struct BLANK
{
    int x_blank;
    int y_blank;
    int length;
    COLORREF color;
    int thorn_x;                    // 尖刺左端位置 x
    bool is_thorn;                  // 木板是否有尖刺
    int thorn_len = 32;             // 尖刺长度
    int thorn_h = 4;                // 尖刺高度
};

//小球结构体
struct BALL
{
    float x_ball;
    float y_ball;
    int score;
    int r;
    COLORREF color;

}ball;

struct BLANK blank[max_blank];

//定义木板
void init_blanks()
{
    srand(time(NULL));
    for (int i = 0; i < max_blank; i++)
    {
        if (i == 0)
        {
            blank[0].y_blank = rand() % 780;
        }
        else
        {
            blank[i].y_blank = blank[i - 1].y_blank + max_distance;
        }
        blank[i].x_blank = rand() % 460;
        blank[i].length = rand() % 50 + 100;
        blank[i].color = RGB(rand() % 256, rand() % 256, rand() % 256);
        blank[i].is_thorn = rand() % 2; // 随机决定是否有尖刺
        if (blank[i].is_thorn)
        {
            blank[i].thorn_x = blank[i].x_blank + rand() % (blank[i].length - blank[i].thorn_len); // 随机设置尖刺位置
        }
    }
}

//定义小球
void init_ball()
{
    ball.r = 6;
    ball.x_ball = blank[1].x_blank + rand() % blank[1].length;
    ball.y_ball = blank[1].y_blank - ball.r;
    ball.score = 0;
    ball.color = blank[1].color;
}

//绘制木板
void draw_blanks()
{
    for (int i = 0; i < max_blank; i++)
    {
        // 绘制木板
        setfillcolor(blank[i].color);
        solidrectangle(blank[i].x_blank, blank[i].y_blank, blank[i].x_blank + blank[i].length, blank[i].y_blank + 7);

        // 绘制尖刺
        if (blank[i].is_thorn)
        {
            setfillcolor(RED); // 尖刺颜色为红色
            for (int j = blank[i].thorn_x; j < blank[i].thorn_x + blank[i].thorn_len; j += 2 * blank[i].thorn_h)
            {
                // 绘制尖刺的三角形
                POINT points[] = {
                    {j, blank[i].y_blank},
                    {j + blank[i].thorn_h, blank[i].y_blank - blank[i].thorn_h},
                    {j + 2 * blank[i].thorn_h, blank[i].y_blank}
                };
                fillpolygon(points, 3);
            }
        }
    }
}

//绘制小球
void draw_ball()
{
    setfillcolor(ball.color);
    fillcircle(ball.x_ball, ball.y_ball, ball.r); // 使用 fillcircle 填充颜色
    char score[30] = "";
    sprintf_s(score, "Score: %d", ball.score);
    outtextxy(10,10,score); // 显示得分
}

//木板的移动
void move_blanks()
{
    //不同的分数对应不同的下落速度
    for (int i = 0; i < max_blank; i++)
    {
        if (ball.score <= 10)
        {
            blank[i].y_blank -= 2; // 木板下落速度
        }
        if (ball.score <= 15&&ball.score>10)
        {
            blank[i].y_blank -= 3; // 木板下落速度
        }
        if (ball.score <= 25&&ball.score>15)
        {
            blank[i].y_blank -= 5; // 木板下落速度
        }
        if (ball.score > 25)
        {
            blank[i].y_blank -= 7; // 木板下落速度

        }
        
        if (blank[i].y_blank < 0)
        {
            blank[i].y_blank = max_blank * max_distance;
            blank[i].x_blank = rand() % 460;
            blank[i].length = rand() % 50 + 100;
            blank[i].color = RGB(rand() % 256, rand() % 256, rand() % 256);
            ball.score++;
            blank[i].is_thorn = rand() % 2; // 随机决定是否有尖刺
            if (i != 1)
            {
                if (blank[i].is_thorn)
                {
                    blank[i].thorn_x = blank[i].x_blank + rand() % (blank[i].length - blank[i].thorn_len); // 随机设置尖刺位置
                }
            }
                
            
        }
    }
}


int width = 560;
int height = 780;
float vy = 0;
float g = 0.2;
float target_x_ball = 0; // 初始化为 0
bool is_dead = false;    // 是否死亡

bool check_collision_with_thorn(float x, float y)
{
    for (int i = 0; i < max_blank; i++)
    {
        if (blank[i].is_thorn)
        {
            // 检查小球是否在尖刺的范围内
            if (x + ball.r >= blank[i].thorn_x && x - ball.r <= blank[i].thorn_x + blank[i].thorn_len &&
                y + ball.r >= blank[i].y_blank - blank[i].thorn_h && y - ball.r <= blank[i].y_blank)
            {
                return true; // 碰撞到尖刺
            }
        }
    }
    return false; // 未碰撞到尖刺
}

// 开始介绍界面
void Introduce()
{
    setbkcolor(BLACK); // 设置背景颜色为黑色
    cleardevice();     // 清屏

    // 绘制标题
    settextcolor(LIGHTMAGENTA);
    settextstyle(50, 0, _T("黑体"));
    outtextxy((width - textwidth(_T("地下一百层"))) / 2, height / 5, _T("地下一百层"));

    // 绘制操作提示
    settextcolor(GREEN);
    settextstyle(25, 0, _T("黑体"));
    outtextxy((width - textwidth(_T("按 Enter 开始游戏"))) / 2, height / 5 * 2 + 20, _T("按 Enter 开始游戏"));
    outtextxy((width - textwidth(_T("按 ESC 退出游戏"))) / 2, height / 5 * 2 + 60, _T("按 ESC 退出游戏"));

    // 控制方向提示
    outtextxy((width - textwidth(_T("控制方向: 左右方向键, AD, 鼠标左右键"))) / 2, height / 5 * 2 + 100, _T("控制方向: 左右方向键, AD, 鼠标左右键"));

    // 添加游戏目标提示
    settextcolor(BLUE);
    outtextxy((width - textwidth(_T("目标: 尽量躲避尖刺并持续生存"))) / 2, height / 5 * 2 + 140, _T("目标: 尽量躲避尖刺并持续生存"));

    // 绘制按钮
    int start_x = width / 2 - 100;
    int start_y = height / 4 * 3;
    int exit_x = width / 2 + 20;
    int exit_y = height / 4 * 3;
    setfillcolor(LIGHTGRAY);
    solidrectangle(start_x, start_y, start_x + 80, start_y + 40);
    settextcolor(BROWN);
    outtextxy(start_x + 20, start_y + 10, _T("开始"));

    setfillcolor(LIGHTGRAY);
    solidrectangle(exit_x, exit_y, exit_x + 80, exit_y + 40);
    settextcolor(BROWN);
    outtextxy(exit_x + 20, exit_y + 10, _T("退出"));

    FlushBatchDraw();

    // 检测鼠标点击或键盘输入
    MOUSEMSG msg;
    bool selected = false;
    while (!selected)
    {
        while (MouseHit())
        {
            msg = GetMouseMsg();

            // 点击“开始”按钮
            if (msg.x >= start_x && msg.x <= start_x + 80 && msg.y >= start_y && msg.y <= start_y + 40 && msg.uMsg == WM_LBUTTONDOWN)
            {
                selected = true;
                break;
            }
            // 点击“退出”按钮
            else if (msg.x >= exit_x && msg.x <= exit_x + 80 && msg.y >= exit_y && msg.y <= exit_y + 40 && msg.uMsg == WM_LBUTTONDOWN)
            {
                exit(0);
            }
        }

        // 检测键盘输入
        if (_kbhit())
        {
            char input = _getch();
            if (input == 13) // Enter 键
            {
                selected = true;
                break;
            }
            else if (input == 27) // ESC 键
            {
                exit(0);
            }
        }

        Sleep(16);
    }
}

int main()
{
    initgraph(width, height);
    init_blanks();
    init_ball();

    setfillstyle(SOLID_FILL, YELLOW);
    BeginBatchDraw();

    // 显示开始介绍界面
    Introduce();

    target_x_ball = ball.x_ball; // 初始化目标位置

    while (1)
    {
        // 检测鼠标输入
        if (MouseHit())
        {
            MOUSEMSG msg = GetMouseMsg();
            // 检测鼠标左键按下
            if (msg.uMsg == WM_LBUTTONDOWN)
            {
                target_x_ball -= 10; // 向左
            }
            // 检测鼠标右键按下
            else if (msg.uMsg == WM_RBUTTONDOWN)
            {
                target_x_ball += 10; // 向右
            }
        }

        // 检测键盘输入
        if (_kbhit())
        {
            char input = _getch();
            if (input == 'a') // 向左
                target_x_ball -= 10; // 移动目标位置
            else if (input == 'd') // 向右
                target_x_ball += 10; // 移动目标位置
            else if (input == 's') // 向下
                vy = 10;
            else if (input == 'q') // 退出
                break;
        }

        // 更新速度和位置
        vy += g;
        ball.y_ball += vy;

        // 边界处理
        if (ball.x_ball - ball.r < 0)
        {
            ball.x_ball = ball.r;
            break;
        }
        if (ball.x_ball + ball.r > width)
        {
            ball.x_ball = width - ball.r;
            break;
        }
        if (ball.y_ball + ball.r > height)
        {
            vy = 0;
        }
        if (ball.y_ball - ball.r < 0 || ball.y_ball + ball.r > height) // 碰到上下边界时游戏结束
        {
            is_dead = true;
            break;
        }

        // 平滑移动
        ball.x_ball += (target_x_ball - ball.x_ball) * 0.1; // 使用插值法平滑移动

        // 碰撞检测
        for (int i = 0; i < max_blank; i++)
        {
            if ((ball.x_ball >= blank[i].x_blank && ball.x_ball <= blank[i].x_blank + blank[i].length) &&
                (ball.y_ball + ball.r >= blank[i].y_blank && ball.y_ball - ball.r <= blank[i].y_blank + 7))
            {
                ball.y_ball = blank[i].y_blank - ball.r;
                vy = 0;
                break;
            }
        }

        // 检测是否碰到尖刺
        if (check_collision_with_thorn(ball.x_ball, ball.y_ball))
        {
            is_dead = true;
            break; // 游戏结束
        }

        cleardevice();
        draw_blanks();
        draw_ball();
        move_blanks();
        FlushBatchDraw();
        Sleep(20);
    }

    if (is_dead)
    {
        // 显示游戏结束信息
        settextstyle(40, 0, _T("宋体"));
        outtextxy(width / 2 - 100, height / 2 - 20, _T("Game Over"));
        FlushBatchDraw();
        Sleep(2000); // 暂停2秒
    }

    EndBatchDraw();
    closegraph();
    return 0;
}
